package com.study.study.pool;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 功能描述：连接池基类
 * <p>
 * author: ZACK
 * date: 2021/2/7 22:57
 */
public abstract class ConnPool<T> {


    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final Lock lock = new ReentrantLock();
    private int initSize;
    private int maxSize;
    private volatile boolean initialized;

    private volatile boolean closed;

    private BlockingQueue<T> container;

    private final int pollingCount = 0;


    public void init() throws ConnPoolException {

        if (initialized) {
            return;
        }
        Lock lock = this.lock;

        try {
            lock.lockInterruptibly();
        } catch (InterruptedException e) {
            throw new ConnPoolException();
        }

        if (initialized) {
            return;
        }

        if (initSize < maxSize) {
            throw new ConnPoolException();
        }

        try {

            initCheck();

            container = new LinkedBlockingQueue<>(maxSize);

            ConnPoolException poolException = null;

            try {
                for (int i = 0; i < initSize; i++) {
                    T t = makeObject();
                    if (t != null && validate(t)) {
                        container.put(t);
                    }
                }
            } catch (ConnPoolException e) {
                logger.error("init connectPool error: ", e);
                poolException = e;
            }

            if (container.size() == 0 && poolException != null) {
                throw poolException;
            }
        } catch (InterruptedException e) {

        } catch (RuntimeException e) {

        } catch (Error e) {

        }


    }

    /**
     * 实现功能:
     * <p>
     * author ZACK
     * date  2021/2/7
     * param []
     * return void
     */
    protected abstract void initCheck();

    /**
     * 实现功能: 获取对象
     * <p>
     * author ZACK
     * date  2021/2/7
     * param []
     * return T
     */
    public T getClient() {
        return null;
    }

    /**
     * 实现功能:
     * <p>
     * author ZACK
     * date  2021/2/7
     * param [time]
     * return T
     */
    public T getClient(long time) {
        return null;
    }

    /**
     * 实现功能: 校验连接的有效性
     * <p>
     * author ZACK
     * date  2021/2/7
     * param [t]
     * return boolean
     */
    public abstract boolean validate(T t);

    /**
     * 实现功能: 创建连接
     * <p>
     * author ZACK
     * date  2021/2/7
     * param []
     * return T
     */
    protected abstract T makeObject() throws ConnPoolException;

    /**
     * 实现功能: 销毁对象
     * <p>
     * author ZACK
     * date  2021/2/7
     * param [t]
     * return void
     */
    protected abstract void destroy(T t);

    public void releaseAll() {

    }

}
